package engine;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

import tower.BigCannon;
import tower.MachineAntiArmor;
import tower.MachineGun30mm;
import tower.SmallCannon;
import tower.V2Launcher;

import constans.Flag;
import constans.Globals;
import constans.ResourceManager;
import controller.GameController;
import controller.ObjectController;
import describe.MyBuildingDescribe;
import entity.Building;
import entity.Entity;
import entity.Unit;

public class Map {

		private ObjectController objectController = GameController.objectController;
		
		//poruszanie ekranu
		public static int dx = 0;
		private int screenMoveSpeed = 5;
		private int margin = 15;
		//puszczanie jednostek
		private static int time = 0;
		private static int dTime = 500;
		//nawierzhcnia
		private boolean canDrawNet = false;		
		private Sector[][] sector;
		
		//cien budynku
		private Building buildingShadow;
		private boolean build;
		private int buildingType;
		
		private Entity describe;
		
		public Map()
		{
			sector = new Sector[Globals.SECTOR_I][Globals.SECTOR_J];
			for(int i = 0 ; i <Globals.SECTOR_I ; i++)
				for(int j = 0 ; j < Globals.SECTOR_J ; j++)
					sector[i][j] = new Sector(Globals.MAP_START + i*Globals.SECTOR_SIZE,Globals.MAP_START + j *  Globals.SECTOR_SIZE);
		}
		public void render(GameContainer container, Graphics g) throws SlickException
		{	
			for(Sector[] s1 : sector)
				for( Sector s2 : s1)
					s2.render(container, g);

			if(build)
				drawNet(g);
			objectController.render(container, g);
			if(build)
				buildingShadow.render(container, g);

		}
		public void update(GameContainer container, int delta) throws SlickException
		{
			time++;
			if(time%dTime == 0)
			{
				objectController.addUnit(new Unit(ObjectController.getBegin()));
				time = 0;
				if(dTime > 100)
					dTime -= 2;
			}
			objectController.update(container, delta);
			
			Input input = container.getInput();
			//przesuwanie ekranu
			if(input.getMouseX() < margin){
				dx += screenMoveSpeed;
			}
			else if(input.getMouseX() > Globals.WIDTH - margin){
				dx -= screenMoveSpeed;
			}
			if(dx > 0) dx = 0;
			else if(dx < -900) dx = -900; //na czuja ta liczbe ustalilem
			
			//cien budynku && budowanie
			if(build)
			{
				buildingShadow.setPosition(input.getMouseX() - Map.dx, input.getMouseY());
				if(isOnScreen(input.getMouseX(), input.getMouseY()))
				{
					buildingShadow.canDraw(true);
					if(objectController.isFieldEmpty(buildingShadow.getI(), buildingShadow.getJ()))
					{
						if(ObjectController.player.getMoney() >= buildingShadow.getPrice())
						{		
							buildingShadow.canBuild(true);
							buildingShadow.setRangeDrawing(true);
							if(input.isMousePressed(Input.MOUSE_LEFT_BUTTON))
							{
								objectController.addBuilding(buildingShadow);
								build(true, buildingType);
							}			
						}
						else buildingShadow.canBuild(false);	
					}
					else buildingShadow.canBuild(false);	
				}
				else buildingShadow.canDraw(false);				
			}
			else
			{
				if(input.isMousePressed(Input.MOUSE_LEFT_BUTTON))
					if(isOnScreen(input.getMouseX(), input.getMouseY()))
					{
						objectController.dontDrawRanges();
						describe = objectController.isOnEntity(input.getMouseX() - Map.dx, input.getMouseY());						
					}
			}
		}
		private void drawNet(Graphics g)
		{
			g.setColor(Color.gray);
			for(int i = 0 ; i < Globals.MAP_SIZE_X/Globals.FIELD_SIZE ; i++)
				g.drawLine(dx + Globals.MAP_START + i*Globals.FIELD_SIZE,Globals.MAP_START,dx + Globals.MAP_START + i*Globals.FIELD_SIZE,Globals.MAP_SIZE_Y + Globals.MAP_START);
			for(int i = 0 ; i < Globals.MAP_SIZE_Y/Globals.FIELD_SIZE ; i++)
				g.drawLine(Globals.MAP_START,Globals.MAP_START + i*Globals.FIELD_SIZE,Globals.MAP_START + Globals.MAP_SIZE_X,Globals.MAP_START + i*Globals.FIELD_SIZE);
		}
		public void build(boolean b, int type)
		{
			buildingType = type;
			build = b;
			if(b)
			{
				switch(type)
				{
				case Flag.SMALL_CANNON:
					buildingShadow = new SmallCannon(-100,-100);
					break;
				case Flag.BIG_CANNON:
					buildingShadow = new BigCannon(-100,-100);
					break;
				case Flag.MACHINE_GUN:
					buildingShadow = new MachineGun30mm(-100,-100);
					break;	
				case Flag.V2LAUNCHER:
					buildingShadow = new V2Launcher(-100,-100);
					break;
				case Flag.MACHINE_AA:
					buildingShadow = new MachineAntiArmor(-100,-100);
					break;	
					
				}
				objectController.dontDrawRanges();
				objectController.unpickAll();
				//no money
				if(ObjectController.player.getMoney() < buildingShadow.getPrice())
				{
					//build(false, type);				
					buildingShadow.canBuild(false);
				}
			}
		}
		private boolean isOnScreen(int mx, int my)
		{
			if(mx >= Globals.SCREEN_SIZE + Globals.MAP_START) return false;
			if(mx <= Globals.MAP_START) return false;
			if(my >= Globals.SCREEN_SIZE + Globals.MAP_START) return false;
			if(my <= Globals.MAP_START) return false;
			return true;		
		}
		public Entity getDescribe()
		{	
				
			if(objectController.isAlive(describe))
				return describe;
	
			return null;
		}

}
